package cn.tedu.csmall.product.service.impl;

import cn.tedu.csmall.commons.ex.ServiceException;
import cn.tedu.csmall.commons.pojo.vo.PageData;
import cn.tedu.csmall.commons.util.PageInfoToPageDataConverter;
import cn.tedu.csmall.commons.web.ServiceCode;
import cn.tedu.csmall.product.mapper.*;
import cn.tedu.csmall.product.pojo.entiry.Spu;
import cn.tedu.csmall.product.pojo.entiry.SpuDetail;
import cn.tedu.csmall.product.pojo.param.SpuAddNewParam;
import cn.tedu.csmall.product.pojo.param.SpuUpdateInfoParam;
import cn.tedu.csmall.product.pojo.vo.*;
import cn.tedu.csmall.product.service.*;
import cn.tedu.csmall.product.util.IdUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * csmall-server-jh
 * <p>
 * SPU的实现类
 *
 * @author: 姜衡
 * @create: 2024-09-26 16:09
 **/

@Slf4j
@Service
public class SpuServiceImpl implements ISpuService {

    @Value("${csmall.crud.default-query-page-size}")
    private Integer defaultQuerySize;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private BrandMapper brandMapper;
    @Autowired
    private AttributeTemplateMapper attributeTemplateMapper;
    @Autowired
    private AlbumMapper albumMapper;
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private SpuDetailMapper spuDetailMapper;
    @Autowired
    private IdUtils idUtils;

    @Override
    public void addNew(SpuAddNewParam spuAddNewParam) {
        log.debug("开始处理【新增SPU】的业务，参数：{}", spuAddNewParam);

        // 检查类别是否存在，是否被禁用，是否有子级类别
        CategoryStandardVO categoryStandardVO = categoryMapper.getStandardById(spuAddNewParam.getCategoryId());
        if (categoryStandardVO == null) {
            String message = "新增SPU失败，相关类别数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        if (categoryStandardVO.getEnable() == 0) {
            String message = "新增SPU失败，相关类别数据被禁用！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        if (categoryStandardVO.getIsParent() == 1) {
            String message = "新增SPU失败，相关类别数据下还有其他子级类别！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 检查品牌是否存在，是否被禁用
        BrandStandardVO brandStandardVO = brandMapper.getStandard(spuAddNewParam.getBrandId());
        if (brandStandardVO == null) {
            String message = "新增SPU失败，相关品牌数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        if (categoryStandardVO.getEnable() == 0) {
            String message = "新增SPU失败，相关品牌数据被禁用！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 检查属性模板是否存在
        AttributeTemplateStandardVO attributeTemplateStandardVO = attributeTemplateMapper.getById(spuAddNewParam.getAttributeTemplateId());
        if (attributeTemplateStandardVO == null) {
            String message = "新增SPU失败，相关属性模板数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 检查相册是否存在
        AlbumStandardVO albumStandardVO = albumMapper.getAlbumStandardById(spuAddNewParam.getAlbumId());
        if (albumStandardVO == null) {
            String message = "新增SPU失败，相关相册数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 添加SPU
        // 获取SPU ID
        Long spuId = idUtils.generateSpuId();
        Spu spu = new Spu();
        BeanUtils.copyProperties(spuAddNewParam, spu);
        // 补全属性值：id
        spu.setId(spuId);
        // 补全属性质：sales, comment_count, positive_comment_count >>> 0
        spu.setSales(0);
        spu.setCommentCount(0);
        spu.setPositiveCommentCount(0);
        // 补全属性值：is_deleted, is_published, is_new_arrival, is_recommend >>> 0
        spu.setIsDeleted(0);
        spu.setIsPublished(0);
        spu.setIsNewArrival(0);
        spu.setIsRecommend(0);
        // 补全属性值：is_checked >>> 0, check_user >>> null
        spu.setIsChecked(0);
        spu.setCheckUser(null);
        // 补全属性值：gmt_create,gmt_modified,gmt_check >>> LocalDateTime.now()
        spu.setGmtCheck(LocalDateTime.now());
        spu.setGmtCreate(LocalDateTime.now());
        spu.setGmtModified(LocalDateTime.now());
        int rows = spuMapper.insert(spu);
        if (rows != 1) {
            String message = "添加SPU失败，服务器正忙，请稍后再试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }

        // 添加SPU详情
        SpuDetail spuDetail = new SpuDetail();
        // 补全属性值：spu_id >>> 与以上Spu的ID相同
        spuDetail.setSpuId(spuId);
        log.debug("spuId={}", spuId);
        // 补全属性值：detail >>> 来自参数
        spuDetail.setDetail(spuAddNewParam.getDetail());
        // 补全属性值：gmt_create,gmt_modified >>> LocalDateTime.now()
        spuDetail.setGmtCreate(LocalDateTime.now());
        spuDetail.setGmtModified(LocalDateTime.now());
        int otherRows = spuDetailMapper.insert(spuDetail);
        if (otherRows != 1) {
            String message = "添加SPU失败，服务器正忙，请稍后再试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }

    @Override
    public void delete(Long id) {
        log.debug("开始处理【根据id删除SPU】的业务，参数ID：{}", id);

        // 检查SPU是否存在，若不存在，则抛出异常
        SpuStandardVO standard = spuMapper.getStandard(id);
        if (standard == null) {
            String message = "删除SPU失败，该SPU不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 删除SPU表的数据
        int rows1 = spuMapper.deleteById(id);
        if (rows1 != 1) {
            String message = "删除SPU失败，服务器正忙1，请稍后再试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 删除SPU详情表的数据
        SpuDetailStandardVO spuDetailStandardVO = spuDetailMapper.getSpuBySpuId(id);
        int rows2 = spuDetailMapper.deleteById(spuDetailStandardVO.getId());
        if (rows2 != 1) {
            String message = "删除SPU失败，服务器正忙2，请稍后再试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        log.debug("删除完成！");
    }

    @Override
    public void updateIsNewArrival(Long id) {
        log.debug("开始处理【设置为新品】业务，参数ID：{}", id);
        updateIsNewArrivalById(id, 1);
    }

    @Override
    public void updateNoNewArrival(Long id) {
        log.debug("开始处理【设置非新品】业务，参数ID：{}", id);
        updateIsNewArrivalById(id, 0);
    }

    @Override
    public void updateIsRecommend(Long id) {
        log.debug("开始处理【设置为推荐】业务，参数ID：{}", id);
        updateIsRecommendById(id, 1);
    }

    @Override
    public void updateNoRecommend(Long id) {
        log.debug("开始处理【设置为非推荐】业务，参数ID：{}", id);
        updateIsRecommendById(id, 0);
    }

    @Override
    public void update(Long id, SpuUpdateInfoParam spuUpdateInfoParam) {
        log.debug("开始处理【根据id修改SPU详情】业务，参数ID：{},更新的数据：{}", id, spuUpdateInfoParam);

        // 检查SPU是否存在，若不存在，则抛出异常
        SpuStandardVO standard = spuMapper.getStandard(id);
        if (standard == null) {
            String message = "修改SPU详情失败，该SPU不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 执行修改
        Spu spu = new Spu();
        spu.setId(id);
        BeanUtils.copyProperties(spuUpdateInfoParam, spu);
        spu.setGmtModified(LocalDateTime.now());
        int rows1 = spuMapper.updateById(spu);
        if (rows1 != 1) {
            String message = "修改SPU详情失败1，服务器正忙，请稍后再试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }

        // 通过spu的id获取spuDetail详情
        SpuDetailStandardVO spuDetailStandardVO = spuDetailMapper.getSpuBySpuId(id);
        SpuDetail spuDetail = new SpuDetail();
        spuDetail.setId(spuDetailStandardVO.getId());
        spuDetail.setDetail(spuUpdateInfoParam.getDetail());
        spuDetail.setGmtModified(LocalDateTime.now());
        int rows2 = spuDetailMapper.updateById(spuDetail);
        if (rows2 != 1) {
            String message = "修改SPU详情失败2，服务器正忙，请稍后再试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
        log.debug("修改完成！");
    }

    @Override
    public SpuStandardVO getStandardById(Long id) {
        log.debug("开始处理【根据id获取SPU详情】的业务，参数ID：{}", id);

        SpuStandardVO standard = spuMapper.getStandard(id);
        log.debug("查询到的数据：{}",standard);
        if (standard == null) {
            String message = "根据id获取SPU详情失败，SPU不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        log.debug("根据id获取SPU详情，即将返回的数据：{}", standard);
        return standard;
    }

    @Override
    public SpuFullInfoVO getFullInfoById(Long id) {
        log.debug("开始处理【根据id查询SPU完整信息】的业务，参数id：{}", id);

        SpuFullInfoVO spuFullInfo = spuMapper.getFullInfo(id);
        if (spuFullInfo == null) {
            String message = "根据id获取SPU详情失败，SPU不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        log.debug("根据id查询SPU完整信息，即将返回的数据：{}", spuFullInfo);
        return spuFullInfo;
    }

    @Override
    public SpuEditListVO getEditInfo(Long id) {
        log.debug("开始处理【根据id查询编辑对话框的SPU信息】的业务，参数ID：{}", id);

        SpuEditListVO editInfo = spuMapper.getEditInfo(id);
        if (editInfo == null) {
            String message = "根据id查询编辑对话框的SPU信息，SPU数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        log.debug("根据id查询编辑对话框的SPU信息，即将返回的数据：{}", editInfo);
        return editInfo;
    }

    @Override
    public PageData<SpuListItemVO> getList(Integer pageNum) {
        log.debug("开始处理【获取SPU数据列表】的业务，页码：{}", pageNum);
        return getList(pageNum, defaultQuerySize);
    }

    @Override
    public PageData<SpuListItemVO> getList(Integer pageNum, Integer pageSize) {
        log.debug("开始处理【获取SPU数据列表】的业务，页码：{},每页记录数：{}", pageNum, pageSize);
        PageHelper.startPage(pageNum, pageSize);
        List<SpuListItemVO> list = spuMapper.getList();
        PageInfo<SpuListItemVO> pageInfo = new PageInfo<>(list);
        return PageInfoToPageDataConverter.convert(pageInfo);
    }

    @Override
    public PageData<SkuListItemVO> getSkuListBySpuList(Long id, Integer pageNum, Integer pageSize) {
        log.debug("开始处理【根据SPU_ID查询SKU列表】的业务，SPU_ID:{},页码：{},每页记录数:{}",id, pageNum, defaultQuerySize);

        PageHelper.startPage(pageNum, defaultQuerySize);
        List<SkuListItemVO> list = spuMapper.getSkuListBySpuList(id);
        PageInfo<SkuListItemVO> pageInfo = new PageInfo<>(list);
        return PageInfoToPageDataConverter.convert(pageInfo);
    }

    private void updateIsNewArrivalById(Long id, Integer isNewArrival) {

        // 查询SPU是否存在，不存在则抛出异常
        SpuStandardVO standard = spuMapper.getStandard(id);
        if (standard == null) {
            String message = IS_NEW_ARRIVAL_Text[isNewArrival] + "SPU设置失败，该SPU数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 判断查询结果中的isNewArrival与参数isNewArrival是否相同，如果是，则抛出异常（当前状态与目标状态相同，没必要执行更新）
        if (standard.getIsNewArrival() == isNewArrival) {
            String message = IS_NEW_ARRIVAL_Text[isNewArrival] + "SPU设置失败，该SPU已经设置为新品！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 执行修改
        Spu spu = new Spu();
        spu.setId(id);
        spu.setIsNewArrival(isNewArrival);
        int rows = spuMapper.updateById(spu);
        if (rows != 1) {
            String message = IS_NEW_ARRIVAL_Text[isNewArrival] + "SPU设置失败，服务器正忙，请稍后再试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
        log.debug("{}SPU设置完成！", IS_NEW_ARRIVAL_Text[isNewArrival]);
    }

    private void updateIsRecommendById(Long id, Integer isRecommend) {

        // 检查SPU是否存在，不存在则抛出异常
        SpuStandardVO standard = spuMapper.getStandard(id);
        if (standard == null) {
            String message = IS_RECOMMEND_TEXT[isRecommend] + "SPU设置失败，该SPU不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 判断结果中的isRecommend与参数isRecommend是否相同，如果是，则抛出异常（当前状态与目标状态相同，没必要执行更新）
        if (standard.getIsRecommend() == isRecommend) {
            String message = IS_RECOMMEND_TEXT[isRecommend] + "SPU设置失败，该SPU已经是推荐状态！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 执行更新
        Spu spu = new Spu();
        spu.setId(id);
        spu.setIsRecommend(isRecommend);
        int rows = spuMapper.updateById(spu);
        if (rows != 1) {
            String message = IS_RECOMMEND_TEXT[isRecommend] + "SPU设置失败，服务器正忙，请稍后再试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
        log.debug("{}SPU设置完成！", IS_RECOMMEND_TEXT[isRecommend]);
    }
}
